#pragma once

#include "TriangleSoupVoxel.h" // Includes also { DistanceVoxel.h, mesh-struct.h };

class DistanceField
{
public:	
	DistanceField(void);
	DistanceField(int nSubVolume, int nSubMesh, MeshStruct* src, MeshStruct* trg);
	~DistanceField(void);	

	BoundingVolume		getBoundingVolume();		// Bounding volume of the source and target meshes
	float				distanceFromPoint(DistanceVoxel *node, float x, float y, float z); // Calculate distance from (x,y,z) to the target mesh
	float*				distanceFromMesh(MeshStruct mesh); // Sum of distances to the target with respect to every vertex of the source
	//DistanceVoxel*		fineVoxelClosestTo(float x, float y, float z);
	TriangleSoupVoxel*	coarseVoxelClosestTo(float x, float y, float z);
	float				computeFromPoint(float x, float y, float z); // (pre-computation stage, off-line)Compute shortest distance from (x, y, z) to the target mesh 

	void				init();							//
	void				split(DistanceVoxel* node);		// 
	void				split(TriangleSoupVoxel* node);		// 
	void				destroy(DistanceVoxel *node);		// ?

	static				int _subDivisionCount;
	float				m_voxelSize;						// Size of the 'cubic' voxel i.e. cube edge lenght/2
	float				m_CoarseVoxelSize;

private:
	void				initTriSoupOctree();				//
	void				initFineGrainOctree();				//
	TriangleSoupVoxel*	closestTo(TriangleSoupVoxel* root, float x, float y, float z);

	DistanceVoxel*		_fineGrainOctree;			// Octree data structure to embody FINE-GRAINED voxels 
	TriangleSoupVoxel*	_triSoupOctree;			// Coarse grained BVH emboding triangle soups
	int					_nSubVolume;		// FINE number of atomic octants (samples) along any of 3 dimensions (x, y, z)
	int					_nSubMesh; // COARSE
	int					_nV;
	
	MeshStruct*			_src;
	MeshStruct*			_trg;
	BoundingVolume		_bv;
};


